package com.leyou.page.service.impl;

import com.leyou.common.dto.*;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.CategoryDTO;
import com.leyou.page.service.GoodsPageService;
import com.leyou.page.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.leyou.page.constants.PageConstant.*;

@Service
public class GoodsPageServiceImpl implements GoodsPageService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ItemClient itemClient;

    /**
     * 加载spu到redis中并返回
     *
     * @param spuId 商品id
     */
    @Override
    public String loadSpuData(Long spuId) {
        //1.查询spu数据
        SpuDTO spuDTO = itemClient.querySpuById(spuId);
        if(spuDTO==null){
            throw  new LyException(404,"商品数据不存在!!!");
        }
        //2.转DTO到VO
        SpuVO spuVO = spuDTO.toEntity(SpuVO.class);
        //3.设置categoryIds的数据
        spuVO.setCategoryIds(spuDTO.getCategoryIds());
        //4.对象转json类型
        String json = JsonUtils.toJson(spuVO);
        //5.写入缓存
        redisTemplate.opsForValue().set(KEY_PREFIX_SPU + spuId, json,30, TimeUnit.MINUTES);
        return json;
    }

    /**
     * 加载spuDetail到redis中并返回
     *
     * @param spuId 商品id
     */
    @Override
    public String loadSpuDetailData(Long spuId) {
        //查询
        SpuDetailDTO spuDetailDTO = itemClient.querySpuDetailById(spuId);
        if(spuDetailDTO==null){
            throw  new LyException(404,"商品数据不存在!!!");
        }
        //序列化
        String json = JsonUtils.toJson(spuDetailDTO);
        //写入缓存
        redisTemplate.opsForValue().set(KEY_PREFIX_DETAIL+spuId, json,30, TimeUnit.DAYS);
        return json;
    }

    /**
     * 加载sku信息到redis中并返回
     *
     * @param spuId 商品id
     */
    @Override
    public String loadSkuListData(Long spuId) {
        //1. 根据id查询spu
        List<SkuDTO> skuDTOList = itemClient.querySkuBySpuId(spuId);
        if(CollectionUtils.isEmpty(skuDTOList)){
            throw  new LyException(404,"商品数据不存在!!!");
        }
        //2. 序列化
        String json = JsonUtils.toJson(skuDTOList);
        //3. 写入缓存
        redisTemplate.opsForValue().set(KEY_PREFIX_SKU+spuId, json,30, TimeUnit.DAYS);
        return json;
    }

    /**
     * 加载分类信息到redis中并返回
     *
     * @param ids 商品分类的三级分类id
     */
    @Override
    public String loadCategoriesData(List<Long> ids) {
        //1.查询
        List<CategoryDTO> categoryDTOList = itemClient.queryCategoryByIds(ids);
        if(CollectionUtils.isEmpty(categoryDTOList)){
            throw  new LyException(404,"商品数据不存在!!!");
        }
        //2.转DTO到VO
        List<CategoryVO> list = categoryDTOList.stream()
                .map(categoryDTO -> categoryDTO.toEntity(CategoryVO.class))
                .collect(Collectors.toList());
        //3.序列化为字符串
        String json = JsonUtils.toJson(list);
        //4.写入到redis,                                        获取第3个category cid3
        redisTemplate.opsForValue().set(KEY_PREFIX_CATEGORY+ids.get(2), json,30, TimeUnit.DAYS);

        return json;
    }

    /**
     * 加载品牌信息到redis中并返回
     *
     * @param brandId 品牌id
     */
    @Override
    public String loadBrandData(Long brandId) {
        //1.查询品牌信息
        BrandDTO brandDTO = itemClient.queryBrandById(brandId);
        if(brandDTO==null){
            throw  new LyException(404,"商品数据不存在!!!");
        }
        //2.转DTO到VO
        BrandVO brandVO = brandDTO.toEntity(BrandVO.class);

        return saveBrandRedis(brandVO);
    }

    @Override
    public void deleteBrandListData(Long id) {
        redisTemplate.delete(KEY_PREFIX_BRAND+id);
    }

    public String saveBrandRedis(BrandVO brandVO) {
        //3.序列化
        String json = JsonUtils.toJson(brandVO);
        //4.写入到redis
        redisTemplate.opsForValue().set(KEY_PREFIX_BRAND+brandVO.getId(), json,30, TimeUnit.DAYS);
        return json;
    }

    /**
     * 加载规格参数信息到redis中并返回
     *
     * @param categoryId 商品第三级分类id
     */
    @Override
    public String loadSpecData(Long categoryId) {

        //1.根据categoryId查询
        List<SpecGroupDTO> groupDTOList = itemClient.querySpecList(categoryId);
        if(CollectionUtils.isEmpty(groupDTOList)){
            throw  new LyException(404,"商品数据不存在!!!");
        }
        //2.获取specGroupVo
        List<SpecGroupVO> groupVoList = new ArrayList<>(groupDTOList.size());
        for (SpecGroupDTO specGroupDTO : groupDTOList) {
            //创建vo
            SpecGroupVO specGroupVO = new SpecGroupVO();
            //赋值
            specGroupVO.setName(specGroupDTO.getName());
            //DTO转vo
            List<SpecParamVO> params = specGroupDTO.getParams().stream()
                    .map(specParamDTO -> specParamDTO.toEntity(SpecParamVO.class))
                    .collect(Collectors.toList());
            specGroupVO.setParams(params);
            //放入集合
            groupVoList.add(specGroupVO);
        }
        //序列化
        String json = JsonUtils.toJson(groupVoList);
        //写入缓存
        redisTemplate.opsForValue().set(KEY_PREFIX_SPEC+categoryId, json,30, TimeUnit.DAYS);
        return json;
    }

    @Override
    public void deleteSkuListData(Long spuId) {
        redisTemplate.delete(KEY_PREFIX_SKU+spuId);
    }
}
